package com.dailyblue.java.project.oa.commons.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dailyblue.java.project.oa.commons.bean.EmpDetails;
import com.dailyblue.java.project.oa.commons.service.EmpService;
import com.dailyblue.java.project.oa.commons.bean.Emp;
import com.dailyblue.java.project.oa.commons.mapper.EmpMapper;
import com.dailyblue.java.project.oa.commons.service.RedisService;
import com.dailyblue.java.project.oa.commons.util.JsonResult;
import com.dailyblue.java.project.oa.commons.util.ResultCode;
import com.dailyblue.java.project.oa.commons.util.ResultTool;
import com.github.pagehelper.PageHelper;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService, UserDetailsService {
    @Resource
    private EmpMapper empMapper;
    @Resource
    private RedisService redisService;

    @Cacheable(cacheNames = "findEmpByECode", key = "#ecode")
    public JsonResult<Integer> findEmpByECode(String ecode) {
        int rows = empMapper.findEmpByECode(ecode);
        if (rows == 0) {
            return ResultTool.success(ResultCode.SUCCESS);
        }
        return ResultTool.fail(ResultCode.COMMON_FAIL);
    }

    @Cacheable(cacheNames = "findEmpByPhone", key = "#phone")
    public JsonResult<Integer> findEmpByPhone(String phone) {
        int rows = empMapper.findEmpByPhone(phone);
        if (rows == 0) {
            return ResultTool.success(ResultCode.SUCCESS);
        }
        return ResultTool.fail(ResultCode.COMMON_FAIL);
    }

    @CachePut(cacheNames = "find", key = "#emp.ecode+','+#emp.pid+','+#emp.deptNo")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public JsonResult saveEmp(Emp emp) {
        boolean row = save(emp);
        redisService.update("find::" + emp.getEcode() + "," + emp.getPid() + "," + emp.getDeptNo());
        return row ? find(emp) : ResultTool.fail(ResultCode.COMMON_FAIL);
    }

    @Cacheable(cacheNames = "find", key = "#emp.ecode+','+#emp.pid+','+#emp.deptNo")
    public JsonResult find(Emp emp) {
        QueryWrapper<Emp> wrapper = new QueryWrapper<>();
        if (emp.getEname() != null) {
            wrapper.like("ename", emp.getEname());
        }
        if (emp.getPid() != null) {
            wrapper.eq("pid", emp.getPid());
        }
        if (emp.getDeptNo() != null) {
            wrapper.eq("deptno", emp.getDeptNo());
        }
        return ResultTool.success(list(wrapper));
    }

    @Cacheable(cacheNames = "find", key = "#page")
    public JsonResult find(int page) {
        PageHelper.startPage(page, 5);
        return ResultTool.success(list());
    }

    @Override
    public JsonResult delete(int id, int nowPage, int allPage) {
        empMapper.deleteById(id);
        redisService.page("find", nowPage, allPage);
        return find(nowPage);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<Emp> wrapper = new QueryWrapper<>();
        wrapper.eq("ecode", username);
        Emp emp = empMapper.selectOne(wrapper);
        if (emp == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        List<GrantedAuthority> list = AuthorityUtils.createAuthorityList("a");
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        EmpDetails empDetails = new EmpDetails(emp,list);
        emp.setEpass(encoder.encode(emp.getEpass()));
        return empDetails;
    }
}
